#pragma once
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<cassert>
const static int defaultfd=-1;
const static int defaultlisten=8;
class server
{
    public:
    server(uint16_t port)
    :_listenfd(defaultfd)
    ,_port(port)
    {}
    ~server()
    {}
    void Init()
    {
        //创建套接字绑定并设置监听状态：
        int ret=socket(AF_INET,SOCK_STREAM,0);
        if(ret<0)
        {
            //套接字创建失败：
            std::cout<<"socket fail!"<<std::endl;
            exit(2);
        }
        _listenfd=ret;
        //给套接字绑定ip与端口
        struct sockaddr_in local;
        local.sin_family=AF_INET;
        local.sin_port=_port;
        local.sin_addr.s_addr=INADDR_ANY;
        socklen_t len=sizeof(local);
        int n=bind(_listenfd,(const struct sockaddr*)&local,len);
        if(n<0)
        {
            std::cout<<"bind fail!"<<std::endl;
            exit(3);
        }
        std::cout<<"bind success!"<<std::endl;
        //设置套接字状态为监听：
        int x=listen(_listenfd,defaultlisten);
        if(x<0)
        {
            std::cout<<"设置listen状态失败！"<<std::endl;
            exit(4);
        }
        std::cout<<"listen success!"<<std::endl;
    }
    void Server(int sockfd)
    {
        while(1)
        {
            char buffer[1024];
            int ret=read(sockfd,buffer,sizeof(buffer)-1);
            if(ret<0)
            {
                std::cout<<"read fail!"<<std::endl;
                close(sockfd);
                break;
            }
            else if(ret==0)
            {
                std::cout<<"client off"<<std::endl;
                close(sockfd);
                break;
            }
            buffer[ret]='0';
            std::cout<<"client say:"<<buffer<<std::endl;
            std::string echostring="echo server#";
            echostring+=buffer;
            int n=write(sockfd,echostring.c_str(),echostring.size());
        }
    }
    void Start()
    {
        while(1)
        {
            //当客户端连接服务器时，获取连接信息并分配文件描述符
            struct sockaddr_in peer;
            socklen_t len=sizeof(peer);
            int sockfd=accept(_listenfd,(struct sockaddr*)&peer,&len);
            if(sockfd<0)
            {
                std::cout<<"accept fail!"<<std::endl;
                exit(5);
            }
            std::cout<<"accept success!"<<std::endl;
            //为客户端提供echoserver服务
            Server(sockfd);
        }
    }
    private:
    int _listenfd;
    uint16_t _port;
};